package org.jeecg.modules.front.controller;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.*;
import org.jeecg.common.util.encryption.EncryptedString;
import org.jeecg.config.JeecgBaseConfig;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.front.entity.vo.LoginUserhome;
import org.jeecg.modules.front.entity.vo.PhoneCode;
import org.jeecg.modules.front.entity.vo.RegisterUserhome;
import org.jeecg.modules.front.entity.vo.UpdateUserhomePhone;
import org.jeecg.modules.gongqiang.entity.Userhome;
import org.jeecg.modules.gongqiang.service.IUserhomeService;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysRoleIndex;
import org.jeecg.modules.system.entity.SysTenant;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.model.SysLoginModel;
import org.jeecg.modules.system.service.*;
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
import org.jeecg.modules.system.util.RandImageUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @Author scott
 * @since 2018-12-17
 */
@RestController
@RequestMapping("/front/user")
@Api(tags = "前台用户基础模块")
@Slf4j
public class LoginUserhomeController {
    @Autowired
    private IUserhomeService userhomeService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private RedisUtil redisUtil;

    @ApiOperation("登录接口")
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public Result<JSONObject> login(@RequestBody LoginUserhome loginUserhome) {
        Result<JSONObject> result = new Result<JSONObject>();
        String phone = loginUserhome.getPhone();
        String password = loginUserhome.getPassword();
        String code = loginUserhome.getCode();
        Integer loginType = loginUserhome.getLoginType();
        if (oConvertUtils.isEmpty(phone)) {
            result.setMessage("手机号不允许为空！");
            result.setSuccess(false);
            return result;
        }
        if (loginType.equals(0)) {
            if (code == null) {
                result.error500("验证码无效");
                return result;
            }
            Object checkCode = redisUtil.get("FULOGIN" + phone);
            if (checkCode == null || !checkCode.toString().equals(code)) {
                result.error500("验证码错误");
                result.setCode(HttpStatus.PRECONDITION_FAILED.value());
                return result;
            }
            redisUtil.del("FULOGIN" + phone);
        }
        LambdaQueryWrapper<Userhome> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Userhome::getPhone, phone);
        Userhome userhome = userhomeService.getOne(queryWrapper);
        if(userhome == null){
            if (loginType.equals(0)) {
                userhome = new Userhome();
                userhome.setUsername(phone);
                userhome.setPhone(phone);
                userhome.setStatus(1);
                userhome.setCreateTime(new Date());
                userhome.setUpdateTime(new Date());
                userhome.setPassword("liuxuanyi"+phone);
                Random random = new Random();
                userhome.setSalt(String.valueOf(random.nextInt(90000000)+10000000));
                userhomeService.save(userhome);
            }else {
                result.error500("该用户不存在，请使用验证码登录");
                return result;
            }
        }else{
            result = userhomeService.checkUserIsEffective(userhome);
            if (!result.isSuccess()) {
                return result;
            }
            if (loginType.equals(0)) {

            } else {
                //2. 校验用户名或密码是否正确
                String userpassword = PasswordUtil.encrypt(String.valueOf(userhome.getId()), password, userhome.getSalt());
                String syspassword = userhome.getPassword();
                if (!syspassword.equals(userpassword)) {
                    result.error500("用户名或密码错误");
                    return result;
                }
            }
        }
        //用户登录信息
        userInfo(userhome, result);
        userhome.setPassword(null);
        userhome.setSalt(null);
        return result;
    }

    /**
     * 用户信息
     *
     * @param
     * @param result
     * @return
     */
    private Result<JSONObject> userInfo(Userhome userhome, Result<JSONObject> result) {
        String phone = userhome.getPhone();
        String syspassword = userhome.getPassword();
        JSONObject obj = new JSONObject(new LinkedHashMap<>());
        // 生成token
        String token = JwtUtil.frontSign(phone, syspassword, userhome.getId());
        // 设置token缓存有效时间
        redisUtil.set("AT" + userhome.getId() + userhome.getPhone(), token);
        redisUtil.expire("AT" + userhome.getId() + userhome.getPhone(), JwtUtil.EXPIRE_TIME * 2 / 1000);
        userhomeService.setAccessToken(userhome.getId(),token);
        obj.put("token", token);
        obj.put("userInfo", userhome);
        result.setResult(obj);
        result.success("登录成功");
        return result;
    }


//    @ApiOperation("注册接口-记得加点击次数限制")
//    @RequestMapping(value = "/register", method = RequestMethod.POST)
//    public Result<JSONObject> register(@RequestBody RegisterUserhome registerUserhome) {
//        Result<JSONObject> result = new Result<JSONObject>();
//        String username = registerUserhome.getUsername();
//        String phone = registerUserhome.getPhone();
//        String password = registerUserhome.getPassword();
//        String code = registerUserhome.getCode();
//        if (oConvertUtils.isEmpty(phone)) {
//            result.setMessage("手机号不允许为空！");
//            result.setSuccess(false);
//            return result;
//        }
//        if (oConvertUtils.isEmpty(password)) {
//            result.setMessage("密码不允许为空！");
//            result.setSuccess(false);
//            return result;
//        }
//        if (code == null) {
//            result.error500("验证码无效");
//            return result;
//        }
//        Object checkCode = redisUtil.get("FULOGIN" + phone);
//        if (checkCode == null || !checkCode.toString().equals(code)) {
//            result.error500("验证码错误");
//            result.setCode(HttpStatus.PRECONDITION_FAILED.value());
//            return result;
//        }
//        redisUtil.del("FULOGIN" + phone);
//        LambdaQueryWrapper<Userhome> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(Userhome::getPhone, phone);
//        Userhome userhome = userhomeService.getOne(queryWrapper);
//        if (userhome != null) {
//            result.error500("手机号已被注册");
//            return result;
//        }
//        userhome = new Userhome();
//        userhome.setUsername(username);
//        userhome.setPhone(phone);
//        userhome.setStatus(1);
//        userhome.setCreateTime(new Date());
//        userhome.setUpdateTime(new Date());
//        userhome.setPassword(password);
//        Random random = new Random();
//        userhome.setSalt(String.valueOf(random.nextInt(90000000)+10000000));
//        userhomeService.save(userhome);
//        String userpassword = PasswordUtil.encrypt(String.valueOf(userhome.getId()), password, userhome.getSalt());
//        userhome.setPassword(userpassword);
//        userhomeService.updateById(userhome);
//        //用户登录信息
//        userInfo(userhome, result);
//        userhome.setPassword(null);
//        userhome.setSalt(null);
//        return result;
//    }

    @ApiOperation("个人信息")
    @RequestMapping(value = "/info", method = RequestMethod.POST)
    public Result<Userhome> info(HttpServletRequest req) {
        Integer userId = JwtUtil.getUserId(req.getHeader("X-Access-Token"));
        Userhome userhome = userhomeService.getById(userId);
        userhome.setPassword(null);
        userhome.setSalt(null);
        return Result.ok(userhome);
    }


    @ApiOperation("修改密码")
    @RequestMapping(value = "/password/up", method = RequestMethod.POST)
    public Result<JSONObject> upPassword(@RequestBody RegisterUserhome registerUserhome, HttpServletRequest req) {
        Result<JSONObject> result = new Result<JSONObject>();
        String username = registerUserhome.getUsername();
        String phone = registerUserhome.getPhone();
        String password = registerUserhome.getPassword();
        //String oldPassword = registerUserhome.getOldPassword();
        String code = registerUserhome.getCode();
        if (oConvertUtils.isEmpty(phone)) {
            result.setMessage("手机号不允许为空！");
            result.setSuccess(false);
            return result;
        }
        if (code == null) {
            result.error500("验证码无效");
            return result;
        }
        if (oConvertUtils.isEmpty(password)) {
            result.setMessage("新密码不允许为空！");
            result.setSuccess(false);
            return result;
        }
//        if (oConvertUtils.isEmpty(oldPassword)) {
//            result.setMessage("旧密码不允许为空！");
//            result.setSuccess(false);
//            return result;
//        }
        Object checkCode = redisUtil.get("FULOGIN" + phone);
        if (checkCode == null || !checkCode.toString().equals(code)) {
            result.error500("验证码错误");
            result.setCode(HttpStatus.PRECONDITION_FAILED.value());
            return result;
        }
        redisUtil.del("FULOGIN" + phone);
        LambdaQueryWrapper<Userhome> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Userhome::getPhone, phone);
        Userhome userhome = userhomeService.getOne(queryWrapper);
        result = userhomeService.checkUserIsEffective(userhome);
        if (!result.isSuccess()) {
            return result;
        }
//        //2. 校验用户名或密码是否正确
//        String userpassword = PasswordUtil.encrypt(String.valueOf(userhome.getId()), oldPassword, userhome.getSalt());
//        String syspassword = userhome.getPassword();
//        if (!syspassword.equals(userpassword)) {
//            result.error500("旧密码错误");
//            return result;
//        }
        Random random = new Random();
        userhome.setSalt(String.valueOf(random.nextInt(90000000)+10000000));
        String userpassword = PasswordUtil.encrypt(String.valueOf(userhome.getId()), password, userhome.getSalt());
        userhome.setPassword(userpassword);
        userhome.setUpdateTime(new Date());
        userhomeService.updateById(userhome);
        result.success("密码修改成功");
        redisUtil.del("AT" + userhome.getId() + userhome.getPhone());
        userhomeService.setAccessToken(userhome.getId(),"token");
        return result;
    }


    @ApiOperation("忘记密码")
    @RequestMapping(value = "/password/forget", method = RequestMethod.POST)
    public Result<JSONObject> forgetPassword(@RequestBody RegisterUserhome registerUserhome, HttpServletRequest req) {
        Result<JSONObject> result = new Result<JSONObject>();
        String username = registerUserhome.getUsername();
        String phone = registerUserhome.getPhone();
        String password = registerUserhome.getPassword();
        String code = registerUserhome.getCode();
        if (oConvertUtils.isEmpty(phone)) {
            result.setMessage("手机号不允许为空！");
            result.setSuccess(false);
            return result;
        }
        if (code == null) {
            result.error500("验证码无效");
            return result;
        }
        if (oConvertUtils.isEmpty(password)) {
            result.setMessage("新密码不允许为空！");
            result.setSuccess(false);
            return result;
        }
        Object checkCode = redisUtil.get("FULOGIN" + phone);
        if (checkCode == null || !checkCode.toString().equals(code)) {
            result.error500("验证码错误");
            result.setCode(HttpStatus.PRECONDITION_FAILED.value());
            return result;
        }
        redisUtil.del("FULOGIN" + phone);
        LambdaQueryWrapper<Userhome> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Userhome::getPhone, phone);
        Userhome userhome = userhomeService.getOne(queryWrapper);
        result = userhomeService.checkUserIsEffective(userhome);
        if (!result.isSuccess()) {
            return result;
        }
        Random random = new Random();
        userhome.setSalt(String.valueOf(random.nextInt(90000000)+10000000));
        String userpassword = PasswordUtil.encrypt(String.valueOf(userhome.getId()), password, userhome.getSalt());
        userhome.setPassword(userpassword);
        userhome.setUpdateTime(new Date());
        userhomeService.updateById(userhome);
        result.success("密码修改成功");
        redisUtil.del("AT" + userhome.getId() + userhome.getPhone());
        userhomeService.setAccessToken(userhome.getId(),"token");
        return result;
    }

    @ApiOperation("更换手机号-确定按钮记得做连点限制，不要出现一连两次请求")
    @RequestMapping(value = "/phone", method = RequestMethod.POST)
    public Result<JSONObject> phone(@RequestBody UpdateUserhomePhone updateUserhomePhone, HttpServletRequest req) {
        Result<JSONObject> result = new Result<JSONObject>();
        String phone = updateUserhomePhone.getPhone();
        String code = updateUserhomePhone.getCode();
        String newPhone = updateUserhomePhone.getNewPhone();
        String newCode = updateUserhomePhone.getNewCode();
        LambdaQueryWrapper<Userhome> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Userhome::getPhone, newPhone);
        Userhome userhome = userhomeService.getOne(queryWrapper);
        if (userhome != null) {
            result.error500("手机号已被使用");
            return result;
        }
        if (oConvertUtils.isEmpty(phone)) {
            result.setMessage("旧手机号不允许为空！");
            result.setSuccess(false);
            return result;
        }
        if (code == null) {
            result.error500("旧手机验证码无效");
            return result;
        }
        if (oConvertUtils.isEmpty(newPhone)) {
            result.setMessage("新手机号不允许为空！");
            result.setSuccess(false);
            return result;
        }
        if (newCode == null) {
            result.error500("新手机验证码无效");
            return result;
        }
        Object checkCode = redisUtil.get("FULOGIN" + phone);
        if (checkCode == null || !checkCode.toString().equals(code)) {
            result.error500("旧手机验证码错误");
            result.setCode(HttpStatus.PRECONDITION_FAILED.value());
            return result;
        }
        checkCode = redisUtil.get("FULOGIN" + newPhone);
        if (checkCode == null || !checkCode.toString().equals(newCode)) {
            result.error500("新手机验证码错误");
            result.setCode(HttpStatus.PRECONDITION_FAILED.value());
            return result;
        }
        redisUtil.del("FULOGIN" + phone);
        redisUtil.del("FULOGIN" + newPhone);

        Integer userId = JwtUtil.getUserId(req.getHeader("X-Access-Token"));
        userhome = userhomeService.getById(userId);
        userhome.setPhone(newPhone);
        userhome.setUpdateTime(new Date());
        userhomeService.updateById(userhome);
        result.success("更换手机号成功");
        redisUtil.del("AT" + userhome.getId() + userhome.getPhone());
        userhomeService.setAccessToken(userhome.getId(),"token");
        return result;
    }


    /**
     * 退出登录
     *
     * @return
     */
    @ApiOperation("退出登录")
    @PostMapping(value = "/logout")
    public Result<Object> logout(HttpServletRequest req) {
        //用户退出逻辑
        String token = req.getHeader(CommonConstant.X_ACCESS_TOKEN);
        if (oConvertUtils.isEmpty(token)) {
            return Result.error("退出登录失败！");
        }
        Integer userId = JwtUtil.getUserId(token);
        Userhome userhome = userhomeService.getById(userId);
        if (userhome != null) {
            redisUtil.del("AT" + userhome.getId() + userhome.getPhone());
            userhomeService.setAccessToken(userhome.getId(),"token");
            return Result.ok("退出登录成功！");
        } else {
            return Result.error("Token无效!");
        }
    }


    /**
     * 头像上传
     *
     * @return
     */
    @ApiOperation("头像上传")
    @PostMapping(value = "/avatar")
    public Result<Object> avatar(@RequestBody Userhome upUserhome,HttpServletRequest req) {
        Integer userId = JwtUtil.getUserId(req.getHeader(CommonConstant.X_ACCESS_TOKEN));
        Userhome userhome = userhomeService.getById(userId);
        if (userhome != null) {
            userhome.setAvatar(upUserhome.getAvatar());
            userhomeService.updateById(userhome);
        }
        return Result.ok("头像修改成功");
    }

    /**
     * 发送短信
     *
     * @return
     */
    @ApiOperation("发送短信")
    @PostMapping(value = "/sms")
    public Result<String> sms(@RequestBody PhoneCode phoneCode) {
        Result<String> result = new Result<String>();
        String mobile = phoneCode.getPhone();
        //手机号模式 登录模式: "2"  注册模式: "1"
        //String smsmode = phoneCode.getType();
        log.info(mobile);
        if(oConvertUtils.isEmpty(mobile)){
            result.setMessage("手机号不允许为空！");
            result.setSuccess(false);
            return result;
        }
        String redisKey = "FULOGIN" + mobile;
        Object object = redisUtil.get(redisKey);
        if (object != null) {
            result.setMessage("验证码1分钟内，仍然有效！");
            result.setSuccess(false);
            return result;
        }
        //随机数
        String captcha = RandomUtil.randomNumbers(6);
        JSONObject obj = new JSONObject();
        obj.put("code", captcha);
        try {
            boolean b = false;
            b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.LOGIN_FRONT_TEMPLATE_CODE);
            if (b == false) {
                result.setMessage("短信验证码发送失败,请稍后重试");
                result.setSuccess(false);
                return result;
            }
            //验证码1分钟内有效
            redisUtil.set(redisKey, captcha, 60);
            result.setSuccess(true);
        } catch (ClientException e) {
            e.printStackTrace();
            result.error500(" 短信接口未配置，请联系管理员！");
            return result;
        }
        return result;
    }
}